package com.situ.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.situ.context.BaseContext;
import com.situ.domain.dto.OrderPageQueryDTO;
import com.situ.domain.dto.OrderReportDTO;
import com.situ.domain.dto.SaveOrderDTO;
import com.situ.domain.entity.*;
import com.situ.domain.vo.*;
import com.situ.mapper.TOrderItemMapper;
import com.situ.mapper.TOrderMapper;
import com.situ.service.AddressService;
import com.situ.service.CartService;
import com.situ.service.OrderItemService;
import com.situ.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class OrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> implements OrderService {

    private final CartService cartService;

    private final OrderItemService orderItemService;

    private final TOrderItemMapper orderItemMapper;

    private final AddressService addressService;

    private final ProductServiceImpl productService;

    private final TOrderMapper orderMapper;


    /**
     * 保存订单/创建新订单
     *
     * @param saveOrderDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveOrder(SaveOrderDTO saveOrderDTO) {
        // 获取当前用户ID
        Integer currentUserId = BaseContext.getCurrentId();
        // 获取购物车列表
        List<TCart> cartList = cartService.listByIds(saveOrderDTO.getCids());
        // 获取收货地址
        TAddress address = addressService.getById(saveOrderDTO.getAid());
        // 构建订单实体
        TOrder order = TOrder.builder()
                .oid(IdUtil.fastSimpleUUID() + System.currentTimeMillis())
                .uid(currentUserId)
                .recvName(address.getName())
                .recvPhone(address.getPhone())
                .recvProvince(address.getProvinceName())
                .recvCity(address.getCityName())
                .recvArea(address.getAreaName())
                .recvAddress(address.getAddress())
                .totalPrice((double) cartList.stream().mapToLong(TCart::getPrice).sum())
                .state(0)
                .orderTime(LocalDateTime.now())
                .payTime(null)
                .createdUser(currentUserId.toString())
                .createdTime(LocalDateTime.now())
                .status(0)
                .build();
        // 保存订单
        this.save(order);
        // 构建订单详情实体列表
        List<TOrderItem> tOrderItems = cartList.stream().map(item -> {
            TProduct product = productService.getById(item.getPid());
            return TOrderItem.builder()
                    .oid(order.getOid())
                    .pid(item.getPid())
                    .title(product.getTitle())
                    .image(product.getImage())
                    .price(item.getPrice())
                    .num(item.getNum())
                    .createdUser(currentUserId.toString())
                    .createdTime(new Date())
                    .build();
        }).toList();
        orderItemService.saveBatch(tOrderItems);
        // 清理购物车
        cartService.removeByIds(saveOrderDTO.getCids());
        return order.getOid();
    }


    /**
     * 获取订单列表
     * @param pageQueryDTO
     * @return
     */
    @Override
    public BasePageQueryVO<TOrder> getOrderList(OrderPageQueryDTO pageQueryDTO) {
        Page<TOrder> page = Page.of(pageQueryDTO.getCurrentPage(), pageQueryDTO.getPageSize());
        this.lambdaQuery()
                .like(StrUtil.isNotBlank(pageQueryDTO.getQueryString()), TOrder::getOid, pageQueryDTO.getQueryString())
                .or()
                .like(StrUtil.isNotBlank(pageQueryDTO.getQueryString()),TOrder::getRecvAddress,pageQueryDTO.getQueryString())
                .page(page);
        return new BasePageQueryVO<>(page.getCurrent(),
                page.getSize(),
                page.getTotal(),
                page.getPages(),
                page.getRecords());
    }


    /**
     * 根据订单id查询用户
     * @param oid
     * @return
     */
    @Override
    public UserInfoVO getUserByOrder(String oid) {
        TUser user = orderMapper.getUserByOrderId(oid);
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtil.copyProperties(user,userInfoVO);
        return userInfoVO;
    }


    /**
     * 根据订单id删除订单
     * @param oid
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrdrById(String oid) {
        this.removeById(oid);
        orderItemService.lambdaUpdate()
                .eq(TOrderItem::getOid,oid)
                .remove();
    }


    /**
     * 获取订单报表
     * @return
     */
    @Override
    public OrderReportVO getOrderReport() {
        OrderReportVO orderReportVO = new OrderReportVO();
        List<OrderReportDTO> orderReportDTO = orderItemMapper.getOrderReport();
        orderReportDTO.forEach(item -> {
            orderReportVO.getXData().add(item.getTitle());
            orderReportVO.getYData().add(OrderReportVO.Y.builder()
                    .name(item.getTitle())
                    .value(item.getTotalNum())
                    .build());
        });
        return orderReportVO;
    }

    /**
     * 获取运营数据订单报表
     * @return
     */
    @Override
    public BussinessReportVO.OrderReport getBussinessOrderReport() {
        Long todayNewOrder = this.lambdaQuery()
                .eq(TOrder::getStatus, 4)
                .ge(TOrder::getOrderTime, DateUtil.beginOfDay(new Date()))
                .count();
        Long thisWeekNewOrder = this.lambdaQuery()
                .eq(TOrder::getStatus, 4)
                .ge(TOrder::getOrderTime, DateUtil.beginOfDay(DateUtil.beginOfWeek(new Date())))
                .count();
        return BussinessReportVO.OrderReport
                .builder()
                .todayNewOrder(todayNewOrder)
                .thisWeekNewOrder(thisWeekNewOrder)
                .build();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void payedOrder(Integer uid, String oid) {
        log.info("用户{}支付订单{}成功", uid, oid);
        // 修改订单状态
        this.lambdaUpdate()
                .eq(TOrder::getOid, oid)
                .set(TOrder::getStatus, 1)
                .set(TOrder::getState,1)
                .set(TOrder::getPayTime, new Date())
                .set(TOrder::getModifiedUser, uid.toString())
                .set(TOrder::getModifiedTime, new Date())
                .update();
        // 查询订单的商品信息:
        List<TOrderItem> orderItems = orderItemService.lambdaQuery()
                .eq(TOrderItem::getOid, oid)
                .list();
        List<TProduct> products = new ArrayList<>();
        orderItems.forEach(item -> {
            TProduct product = productService.getById(item.getPid());
            product.setNum(product.getNum() - item.getNum());
            product.setModifiedUser(uid.toString());
            product.setModifiedTime(new Date());
            products.add(product);
        });
        productService.updateBatchById(products);
    }

    /**
     * 根据用户id和订单状态查询订单列表
     * @param uid
     * @param state
     * @return
     */
    @Override
    public List<OrderAndItemVO> getOrderListByUserState(Integer state) {
        return orderMapper.getOrderListByUserState(state,BaseContext.getCurrentId());
    }
}
